/**
 * @file    pc_comm_frame.c
 * @brief   PC通信数据帧处理服务
 * @details This is the detail description.
 * @author  wang-haoyu
 * @date    2025年7月29日 (created)
 * @version 0.0.2
 * @par Copyright (C):
 *          All Rights Reserved.
 * @par Encoding:
 *          GB2312
 * @par Description        :
 * 1. Hardware Descriptions:
 *      None.
 * 2. Program Architecture:
 *      None.
 * 3. File Usage:
 *      None.
 * 4. Limitations:
 *      None.
 * 5. Else:
 *      None.
 * @par Modification:
 * -# Date          : 2025年7月29日;
 * Revision         : 0.0.1;
 * Author           : wang-haoyu;
 * Contents         : first update
 */
 
/* =============================================================================
 *                                header files
 * ========================================================================== */
#include "pc_comm_frame.h"
#include "crc16.h"
/* =============================================================================
 *                              macros & constants
 * ========================================================================== */

/* =============================================================================
 *                          data structure definitions
 * ========================================================================== */

/* =============================================================================
 *                         static variable definitions
 * ========================================================================== */

/* =============================================================================
 *                         static function definitions
 * ========================================================================== */

/* =============================================================================
 *                         global function definitions
 * ========================================================================== */
/*
 * proto buf通信数据解析函数
 *
 * Parameter:
 *   Input:
 *		-obj：proto buf数据帧句柄
 *   Output:
 * Returns:
 */
pc_comm_err_code pc_comm_unpark_frame_state(pccomm_fifo_port_t fifo_port,pc_comm_frame_t *obj)
{
	rt_int32_t fifo_cnt = 0;
	rt_uint8_t head_buf[sizeof(pc_comm_frame_head_t)] = {0};
	rt_uint8_t head_len = sizeof(pc_comm_frame_head_t);
	rt_uint16_t crc_check = 0;
	
	fifo_cnt = pc_comm_fifo_get_used(&fifo_port);

	if(0 > fifo_cnt) return E_FIFO_LEN_ERR;
	do
	{
		pc_comm_fifo_pick(&fifo_port,head_buf,1);
		if(PC_COMM_HEAD != head_buf[0])
		{
			pc_comm_fifo_cut(&fifo_port,1);
			fifo_cnt--;
			
			if(fifo_cnt < head_len)
				return E_PACK_LEN_ERR;
		}
		else
			break;
	}while(1);
	if(fifo_cnt < head_len) 
		return E_PACK_LEN_ERR;

	pc_comm_fifo_pick(&fifo_port,head_buf,head_len);
	
	rt_memcpy(&obj->head,&head_buf[0],sizeof(obj->head));
	
	if(fifo_cnt < obj->head.data_len + head_len + 3) 
		return E_PACK_LEN_ERR;

	pc_comm_fifo_pick(&fifo_port,obj->all_buf,obj->head.data_len + 6);	
	rt_memcpy(obj->proto_buf,&obj->all_buf[3],obj->head.data_len);
	crc_check = cal_crc16(obj->all_buf,obj->head.data_len + head_len);
	
	pc_comm_fifo_cut(&fifo_port,head_len);
	
	if((PC_COMM_TAIL != obj->all_buf[obj->head.data_len + 5]) || 
		(crc_check != ((obj->all_buf[obj->head.data_len + 4]<<8) | obj->all_buf[obj->head.data_len + 3])))
	{
		return E_CRC_CHECK_ERR;
	}

	pc_comm_fifo_cut(&fifo_port,obj->head.data_len + 3);
	return E_NO_ERR;
}

/*******************************************************************************
 *                                  EOF
 ******************************************************************************/